import { useEffect, useState } from "react";
import { Picker, View } from "@tarojs/components";
import { useDidShow, useRouter, navigateBack } from "@tarojs/taro";
import {
  Layout,
  WithMargins,
  C13BottomDock,
  Header,
  Paragraph,
  KeyValueList,
  Icon,
} from "@/components";
import {
  useUserInfo,
  getUserData,
  returnOrder,
  returnOrderUpdate,
  cancelReturnOrder,
} from "@/store/userDataContext";
import { useAuth } from "@/store/authContext";
import { colors } from "@/data/shared/colors";
import { navigateTo } from "@/utils/navigation";
import { AddressFieldShape } from "@/data/user/userTypes";
import { range } from "lodash-es";
import Taro from "@tarojs/taro";
import { error } from "@/utils";
import style from "./index.module.scss";

// Get dates in range, adapted from https://stackoverflow.com/questions/4413590/javascript-get-array-of-dates-between-2-dates
const getDaysArray = (start, end) => {
  let arr: string[] = [];
  let dt = new Date(start);

  arr.push(new Date(dt).toISOString().slice(0, 10));
  do {
    dt.setDate(dt.getDate() + 1);
    arr.push(new Date(dt).toISOString().slice(0, 10));
  } while (dt <= new Date(end));
  return arr;
};

const padNumber = (number: number) =>
  number < 10 ? `0${number}` : `${number}`;

const TIME_SLOTS = range(8, 20).map(
  (numericVal) => `${padNumber(numericVal)} - ${padNumber(numericVal + 1)}`
);

// Note Luke:
// decode URI of returnEndTime can be of form: "2023-01-23%2000%3A00%3A00"
// I tried to implement around it for now

// I tried to use
{
  /* <Picker
mode="date"
value={currDate}
start={currDate}
// end={endDateMathes![0]}
end={"2023-01-23"}
onChange={(e) => {
  console.log(e.detail.value);
}}
></Picker> */
}
// But in simulator still showed all months, but simply didn't register larger values

// Not done: having the time part prepopulated somehow if already selected before

export default function RefundDelivery() {
  const { dispatchAuthAction } = useAuth();
  const { params } = useRouter();
  const { orderNo, returnEndTime, change } = params;
  const { userInfoState, requestWechatAddress, dispatchUserDataAction } =
    useUserInfo();
  const { userData } = userInfoState;
  const [deliveryAddress, setDeliveryAdress] =
    useState<AddressFieldShape | null>(null);
  const [canChangeDelivery, setCanChangeDelivery] = useState<boolean | string>(
    false
  );

  const [currentHourSh, setCurrentHourSh] = useState(0);
  const [selectedDate, setSelectedDate] = useState<string>("");
  const [selectedTime, setSelectedTime] = useState<string>("");
  const [dateArr, setDateArr] = useState<string[]>([]);
  const [timeArr, setTimeArr] = useState<string[]>([]);

  // Messy with incoming date format as described above
  const endDateMathes = decodeURI(returnEndTime!).match(/\d{4}-\d{2}-\d{2}/);

  // Get current hour
  useEffect(() => {
    const currDate = new Date();

    Taro.request({
      url: `${process.env.apiEndpoint}/order/time`,
      success(result) {
        const serverDate = new Date(result.data.data.time as number);
        setCurrentHourSh(serverDate.getHours());
      },
      fail(res) {
        error(res.errMsg);
      },
    });

    setDateArr(getDaysArray(currDate, new Date(endDateMathes![0])));
  }, [returnEndTime]);

  // Effect for date changes
  useEffect(() => {
    if (selectedDate === dateArr[0]) {
      // Check which are not yet valid
      setTimeArr(
        TIME_SLOTS.filter((timeslot) => +timeslot.split("-")[0] > currentHourSh)
      );
    } else {
      setTimeArr(TIME_SLOTS);
    }
    setSelectedTime("");
  }, [selectedDate]);

  useDidShow(async () => {
    if (!orderNo || !returnEndTime) {
      navigateBack();
    }
    if (!userData?.userInfo.phoneNumber) {
      getUserData(dispatchUserDataAction, userData!, {
        authDispatch: dispatchAuthAction,
      });
    }
  });

  useEffect(() => {
    if (userData?.userInfo.defaultAddress) {
      setDeliveryAdress(userData?.userInfo.defaultAddress);
    }
  }, [userData?.userInfo.phoneNumber]);

  useEffect(() => {
    setCanChangeDelivery(change && change === "1" ? true : false);
  }, [change]);

  // TODO: unclear if canChangeDelivery needs checking here as well
  const rOrder = async () => {
    if (deliveryAddress && selectedDate && selectedTime) {
      const startEndTime = selectedTime
        .split("-")
        .map((time) => `${time.trim()}:00`);
      const query = {
        orderNo: orderNo,
        pickUpDate: selectedDate,
        pickUpStartTime: startEndTime[0],
        pickUpEndTime: startEndTime[1],
        returnUserAddress: `${deliveryAddress.residenceArea.join("")}${
          deliveryAddress.address
        }`,
        returnUserName: deliveryAddress?.name,
        returnUserPhone: deliveryAddress?.phone,
      };
      const r = canChangeDelivery
        ? await returnOrderUpdate({
            query: query,
            authDispatch: dispatchAuthAction,
          })
        : await returnOrder({ query: query, authDispatch: dispatchAuthAction });
      r && navigateBack();
    }
  };

  const cancelROrder = async () => {
    const r = await cancelReturnOrder({
      query: { orderNo: orderNo },
      authDispatch: dispatchAuthAction,
    });
    r && navigateBack();
  };

  useEffect(() => {
    if (userData?.userInfo.defaultAddress) {
      setDeliveryAdress(userData?.userInfo.defaultAddress);
    }
  }, [userData?.userInfo.defaultAddress]);

  return (
    <Layout>
      <>
        <WithMargins>
          <View className={style["refund-delivery-wrapper"]}>
            <Header type="heading-l">寄件详情</Header>

            <View>
              <View className={style["address"]}>
                <View className={style["bottom-border-section"]}>
                  <View
                    className={style["go-to-addresses"]}
                    onClick={() => navigateTo("pages/address-details/index")}
                  >
                    <Header type="heading-s">配送地址</Header>
                    <Icon type="GoToChevron" className={style.chevron} />
                  </View>
                </View>
                <View className={style["bottom-border-section"]}>
                  {/* Depending if there is a primary address or not */}
                  {deliveryAddress && deliveryAddress.id ? (
                    <KeyValueList
                      itemList={[
                        {
                          leftText: "姓名",
                          middleTextTop: deliveryAddress.name,
                        },
                        {
                          leftText: "电话",
                          middleTextTop: deliveryAddress.phone,
                        },
                        {
                          leftText: "地址",
                          middleTextTop: `${deliveryAddress.residenceArea.join(
                            ""
                          )}${deliveryAddress.address}`,
                        },
                      ]}
                    />
                  ) : (
                    <KeyValueList
                      itemList={[
                        {
                          leftText: "收件地址",
                          middleTextTop: "暂无配送信息",
                          middleTextBottom: "手动添加配送信息",
                        },
                        {
                          leftText: "",
                          middleNode: (
                            <View
                              className={style["wechat-icon-text-container"]}
                              onClick={requestWechatAddress}
                            >
                              <Icon type="WeChat" className={style["wechat"]} />
                              <Paragraph
                                color={colors.colorDark}
                                size="small"
                                noSpacing
                              >
                                一键获取微信地址
                              </Paragraph>
                            </View>
                          ),
                        },
                      ]}
                    />
                  )}
                </View>
              </View>
            </View>
          </View>

          <View
            className={`${style["time-section"]} ${style["bottom-border-section"]}`}
          >
            {!selectedDate && !selectedTime ? (
              <View className={style["red"]}>请选择时间</View>
            ) : (
              <View>
                <View>
                  {selectedDate ? (
                    `预约${selectedDate}`
                  ) : (
                    <View className={style["red"]}>请选择上门日期</View>
                  )}
                </View>
                <View>
                  {selectedTime ? (
                    `${selectedTime}上门取件`
                  ) : (
                    <View className={style["red"]}>请选择上门时间</View>
                  )}
                </View>
              </View>
            )}

            <View>
              <Picker
                mode="selector"
                range={dateArr}
                value={0}
                onChange={(e) => {
                  setSelectedDate(dateArr[e.detail.value]);
                }}
              >
                <View className={style.picker}>
                  <Paragraph noSpacing>请选择上门日期</Paragraph>
                  <Icon
                    type="GoToChevron"
                    className={`${style.chevron} ${style["chevron-spacing"]}`}
                  />
                </View>
              </Picker>
              <Picker
                mode="selector"
                range={timeArr}
                value={0}
                onChange={(e) => {
                  setSelectedTime(timeArr[e.detail.value]);
                }}
              >
                <View className={style.picker}>
                  <Paragraph noSpacing>请选择上门时间</Paragraph>
                  <Icon
                    type="GoToChevron"
                    className={`${style.chevron} ${style["chevron-spacing"]}`}
                  />
                </View>
              </Picker>
            </View>
          </View>
        </WithMargins>
        <View className={style["dock-wrapper"]}>
          <C13BottomDock
            onPrimaryClick={{
              cb: rOrder,
              text: canChangeDelivery ? "确认修改" : "立即下单",
            }}
            onSecondaryClick={
              canChangeDelivery
                ? {
                    cb: cancelROrder,
                    text: "取消寄件",
                  }
                : null
            }
          />
        </View>
      </>
    </Layout>
  );
}
